package net.sareweb.acab.entity.manager;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Scope;

@Scope(ScopeType.CONVERSATION)
public class CommonManager<E> {
	@In
	protected EntityManager entityManager;
	protected E instance;
	private Class<E> entityClass;

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public E find(Integer id){
		return (E) entityManager.find(getEntityClass(), id);
	}
	public List<E> findAll(){
		try {
			List<E> l = entityManager.createQuery("from " + getEntityClass().getName()).getResultList();	
			return l;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
			
		 
	}
	
	public void save(Object o){
		entityManager.persist(o);
	}
	
	public void remove(Object o){
		entityManager.remove(o);
	}
	
	public void flush(){
		entityManager.flush();
	}

	public void discardChanges(Object o){
		entityManager.refresh(o);
	}
	
	public EntityTransaction getTransaction() {
		return entityManager.getTransaction();
	}
	
	
	public Class<E> getEntityClass()
	   {
	      if (entityClass == null)
	      {
	         Type type = getClass().getGenericSuperclass();
	         if (type instanceof ParameterizedType)
	         {
	            ParameterizedType paramType = (ParameterizedType) type;
	            if (paramType.getActualTypeArguments().length == 2)
	            {
	               // likely dealing with -> new EntityHome<Person>().getEntityClass()
	               if (paramType.getActualTypeArguments()[1] instanceof TypeVariable)
	               {
	                  throw new IllegalArgumentException("Could not guess entity class by reflection");
	               }
	               // likely dealing with -> new Home<EntityManager, Person>() { ... }.getEntityClass()
	               else
	               {
	                  entityClass = (Class<E>) paramType.getActualTypeArguments()[1];
	               }
	            }
	            else
	            {
	               // likely dealing with -> new PersonHome().getEntityClass() where PersonHome extends EntityHome<Person>
	               entityClass = (Class<E>) paramType.getActualTypeArguments()[0];
	            }
	         }
	         else
	         {
	            throw new IllegalArgumentException("Could not guess entity class by reflection");
	         }
	      }
	      return entityClass;
	   }
}
